package com.demarc.pesquisas.web.mb.entrevista;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.primefaces.model.SortOrder;

import com.demarc.pesquisas.infraestrutura.mensagem.Mensagem;
import com.demarc.pesquisas.infraestrutura.persistencia.ResultadoPaginado;
import com.demarc.pesquisas.infraestrutura.web.jsf.JsfUtil;
import com.demarc.pesquisas.negocio.dto.DetalheEntrevistaDTO;
import com.demarc.pesquisas.negocio.dto.EntrevistaDTO;
import com.demarc.pesquisas.negocio.entidade.SimNaoEnum;
import com.demarc.pesquisas.negocio.entidade.domicilio.Morador;
import com.demarc.pesquisas.negocio.entidade.domicilio.TipoMaterialPredominanteConstrucaoEnum;
import com.demarc.pesquisas.negocio.entidade.entrevista.Entrevista;
import com.demarc.pesquisas.negocio.entidade.entrevista.EntrevistaFiltro;
import com.demarc.pesquisas.negocio.entidade.entrevistador.Entrevistador;
import com.demarc.pesquisas.negocio.entidade.pesquisa.Pesquisa;
import com.demarc.pesquisas.negocio.service.entrevista.IEntrevistaService;
import com.demarc.pesquisas.negocio.service.entrevistador.IEntrevistadorService;
import com.demarc.pesquisas.negocio.util.ConstantesMensagens;
import com.demarc.pesquisas.web.jsf.EntidadeLazyDataModel;
import com.demarc.pesquisas.web.mb.AbstractMB;
import com.demarc.pesquisas.web.pagina.ConstantesPaginas;
import com.demarc.pesquisas.web.pagina.OperacaoEnum;
import com.demarc.pesquisas.web.relatorio.RelatorioDetalheEntrevistaPesquisaFamiliarInaja;
import com.demarc.pesquisas.web.relatorio.TipoRelatorioEnum;

@ManagedBean
@SessionScoped
public class EntrevistaMB extends AbstractMB {

    private static final Logger LOGGER = Logger.getLogger(EntrevistaMB.class);

    @ManagedProperty(value = "#{entrevistaService}")
    private IEntrevistaService entrevistaService;

    @ManagedProperty(value = "#{entrevistadorService}")
    private IEntrevistadorService entrevistadorService;

    private Pesquisa pesquisa;
    private EntrevistaFiltro entrevistaFiltro;
    private Entrevista entrevista;
    private EntrevistaDTO entrevistaSelecionada;
    private List<Entrevistador> entrevistadores;
    private List<String> localidades;
    private EntidadeLazyDataModel<EntrevistaDTO> dataModel;
    private Morador morador;

    @Override
    public String getTituloPagina() {
        return super.getTituloPagina(ConstantesMensagens.LABEL_ENTREVISTA);
    }

    @Override
    public void inicializarPagina() {
        super.setOperacao(OperacaoEnum.DETALHE);
        this.entrevistaFiltro = new EntrevistaFiltro(pesquisa);
        this.morador = new Morador();
        carregarDataModel();
    }

    private void carregarDataModel() {
        this.dataModel = new EntidadeLazyDataModel<EntrevistaDTO>() {

            @Override
            public ResultadoPaginado<EntrevistaDTO> getResult(int first, int pageSize,
                    String sortField, SortOrder sortOrder) {

                entrevistaFiltro.setPesquisa(pesquisa);
                ResultadoPaginado<EntrevistaDTO> entrevistas =
                        entrevistaService.consultar(entrevistaFiltro, first, pageSize, sortField,
                                sortOrder);
                return entrevistas;
            }
        };
    }

    public void salvar() {
        entrevistaService.salvar(entrevista);
        this.entrevista = new Entrevista(this.pesquisa);
        this.morador = new Morador();
        adicionarMensagemInfo(ConstantesMensagens.LABEL_ENTREVISTA);

        LOGGER.info(":::::::::::::::: Entrevista SALVA com sucesso");
    }

    public void alterar() {
        entrevistaService.alterar(entrevista);
        this.morador = new Morador();
        adicionarMensagemInfo(ConstantesMensagens.LABEL_ENTREVISTA);

        LOGGER.info(":::::::::::::::: Entrevista ALTERADA com sucesso");
    }

    public String excluir() {
        entrevistaService.excluir(entrevista);
        LOGGER.info(":::::::::::::::: Entrevista EXCLUÍDA com sucesso");
        return voltarParaListagem();
    }

    public void gerarPdf() {

        List<DetalheEntrevistaDTO> dataSource =
                new ArrayList<DetalheEntrevistaDTO>(Arrays.asList(DetalheEntrevistaDTO
                        .converter(this.entrevista)));

        RelatorioDetalheEntrevistaPesquisaFamiliarInaja relatorio =
                new RelatorioDetalheEntrevistaPesquisaFamiliarInaja(TipoRelatorioEnum.INDIVIDUAL,
                        this.entrevista.getSequencial().toString(), this.entrevista.getDomicilio()
                                .getEndereco().getLocalidade(), this.entrevista.getEntrevistado()
                                .getNome(), dataSource);

        String reportPath =
                FacesContext.getCurrentInstance().getExternalContext()
                        .getRealPath(relatorio.getJasperFileLocation());

        LOGGER.info(reportPath);
        relatorio.generateReportPDF(reportPath);
    }

    public void limparFormulario() {
        this.entrevista = new Entrevista(this.pesquisa);
        this.morador = new Morador();
        JsfUtil.subirPosicaoTela();

        LOGGER.info(":::::::::::::::: LIMPAR FORMULARIO");
    }

    public void limpar() {
        inicializarPagina();
    }

    public String voltar() {
        return avancarParaPagina(ConstantesPaginas.PESQUISA_LISTAGEM_PAGE);
    }

    public String voltarParaListagem() {
        if (!isDetalhe()) {
            inicializarPagina();
        }
        return avancarParaPagina(ConstantesPaginas.ENTREVISTA_LISTAGEM_PAGE);
    }

    public String enviarParaInclusao() {
        super.setOperacao(OperacaoEnum.INCLUSAO);
        this.entrevista = new Entrevista(this.pesquisa);
        this.morador = new Morador();
        LOGGER.info(":::::::::::::::: Enviando para INCLUSÃO");
        return avancarParaPagina(ConstantesPaginas.ENTREVISTA_CRUD_PAGE);
    }

    public String enviarParaImpressao() {
        super.setOperacao(OperacaoEnum.DETALHE);
        LOGGER.info(":::::::::::::::: Enviando para IMPRESSÃO");
        this.entrevista = entrevistaService.buscarPor(entrevistaSelecionada.getId());
        return avancarParaPagina(ConstantesPaginas.ENTREVISTA_CRUD_PAGE);
    }

    public String enviarParaAlteracao() {
        super.setOperacao(OperacaoEnum.ALTERACAO);
        this.morador = new Morador();
        LOGGER.info(":::::::::::::::: Enviando para ALTERAÇÃO");
        this.entrevista = entrevistaService.buscarPor(entrevistaSelecionada.getId());
        return avancarParaPagina(ConstantesPaginas.ENTREVISTA_CRUD_PAGE);
    }

    public String enviarParaExclusao() {
        super.setOperacao(OperacaoEnum.EXCLUSAO);
        LOGGER.info(":::::::::::::::: Enviando para EXCLUSÃO");
        this.entrevista = entrevistaService.buscarPor(entrevistaSelecionada.getId());
        return avancarParaPagina(ConstantesPaginas.ENTREVISTA_CRUD_PAGE);
    }

    public void adicionarMorador() {
        if (morador != null) {
            if (StringUtils.isBlank(morador.getNome())) {
                JsfUtil.adicionarMensagemErro(new Mensagem(
                        ConstantesMensagens.GERAL_CAMPO_OBRIGATORIO_COM_ENTIDADE,
                        ConstantesMensagens.LABEL_NOME, ConstantesMensagens.LABEL_MORADOR));

                JsfUtil.subirPosicaoTela();
                LOGGER.info(":::::::::::::::: Erro ao adicionar Morador no domicílio");
            } else {
                this.entrevista.getDomicilio().adicionarMorador(morador);
                this.morador = new Morador();
                LOGGER.info(":::::::::::::::: Morador ADICIONADO no domicílio com sucesso");
            }
        }
    }

    public void removerMorador() {
        this.entrevista.getDomicilio().removerMorador(morador);
        this.morador = new Morador();
        LOGGER.info(":::::::::::::::: Morador REMOVIDO do domicílio");
    }

    public void listenerTipoMaterialConstrucao() {
        if (!tipoMaterialConstrucaoOutro()) {
            this.entrevista.getDomicilio().setOutroMaterialConstrucao(null);
        }
    }

    public void listenerPossuiPoco() {
        if (!possuiPoco()) {
            this.entrevista.getDomicilio().setTipoVazaoPoco(null);
        }
    }

    public boolean isVisivelOutroTipoMaterial() {
        return tipoMaterialConstrucaoOutro();
    }

    private boolean tipoMaterialConstrucaoOutro() {
        return this.entrevista != null
                && this.entrevista.getDomicilio() != null
                && TipoMaterialPredominanteConstrucaoEnum.OUTRO.equals(this.entrevista
                        .getDomicilio().getTipoMaterialConstrucaoPredominante());
    }

    public boolean isVisivelVazaoPoco() {
        return possuiPoco();
    }

    private boolean possuiPoco() {
        return this.entrevista != null && this.entrevista.getDomicilio() != null
                && SimNaoEnum.SIM.equals(this.entrevista.getDomicilio().getPossuiPoco());
    }

    // Gets and Sets

    public Pesquisa getPesquisa() {
        return pesquisa;
    }

    public void setPesquisa(Pesquisa pesquisa) {
        this.pesquisa = pesquisa;
    }

    public EntrevistaFiltro getEntrevistaFiltro() {
        return entrevistaFiltro;
    }

    public void setEntrevistaFiltro(EntrevistaFiltro entrevistaFiltro) {
        this.entrevistaFiltro = entrevistaFiltro;
    }

    public Entrevista getEntrevista() {
        return entrevista;
    }

    public void setEntrevista(Entrevista entrevista) {
        this.entrevista = entrevista;
    }

    public EntrevistaDTO getEntrevistaSelecionada() {
        return entrevistaSelecionada;
    }

    public void setEntrevistaSelecionada(EntrevistaDTO entrevistaSelecionada) {
        this.entrevistaSelecionada = entrevistaSelecionada;
    }

    public List<Entrevistador> getEntrevistadores() {
        this.entrevistadores = entrevistadorService.listarOrdenadoPor("nome");
        return entrevistadores;
    }

    public void setEntrevistadores(List<Entrevistador> entrevistadores) {
        this.entrevistadores = entrevistadores;
    }

    public List<String> getLocalidades() {
        this.localidades = entrevistaService.listarLocalidades(this.pesquisa);
        return localidades;
    }

    public void setLocalidades(List<String> localidades) {
        this.localidades = localidades;
    }

    public EntidadeLazyDataModel<EntrevistaDTO> getDataModel() {
        return dataModel;
    }

    public void setDataModel(EntidadeLazyDataModel<EntrevistaDTO> dataModel) {
        this.dataModel = dataModel;
    }

    public Morador getMorador() {
        return morador;
    }

    public void setMorador(Morador morador) {
        this.morador = morador;
    }

    public IEntrevistaService getEntrevistaService() {
        return entrevistaService;
    }

    public void setEntrevistaService(IEntrevistaService entrevistaService) {
        this.entrevistaService = entrevistaService;
    }

    public IEntrevistadorService getEntrevistadorService() {
        return entrevistadorService;
    }

    public void setEntrevistadorService(IEntrevistadorService entrevistadorService) {
        this.entrevistadorService = entrevistadorService;
    }
}
